package com.zw.user.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zw.api.SystemFeignClient;
import com.zw.commons.constants.UserConstants;
import com.zw.commons.exception.CustomizeException;
import com.zw.commons.utlis.JwtHelper;
import com.zw.commons.utlis.MD5;
import com.zw.object.result.Result;
import com.zw.object.result.ResultCodeEnum;
import com.zw.object.system.SysRole;
import com.zw.object.system.SysUser;
import com.zw.object.system.SysUserRole;
import com.zw.object.vo.AssginRoleVo;
import com.zw.object.vo.LoginVo;
import com.zw.object.vo.RouterVo;
import com.zw.object.vo.SysUserQueryVo;
import com.zw.user.mapper.SysUserMapper;
import com.zw.user.mapper.SysUserRoleMapper;
import com.zw.user.service.SysUserService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 用户表 服务实现类
 * </p>
 *
 * @author zw
 * @since 2022-12-06
 */
@Slf4j
@Service
public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> implements SysUserService {

    @Autowired
    private SysUserRoleMapper sysUserRoleMapper;
    @Resource
    private SystemFeignClient systemFeignClient;

    /**
     * 获取用户分页列表业务
     *
     * @param iPage          mp 分页对象
     * @param sysUserQueryVo 参数实体类
     * @return Result
     */
    @Override
    public Result sysUserListPage(IPage<SysUser> iPage, SysUserQueryVo sysUserQueryVo) {
        LambdaQueryWrapper<SysUser> queryWrapper = new LambdaQueryWrapper<>();
        if (StringUtils.isNotBlank(sysUserQueryVo.getKeyword())) {
            queryWrapper
                    .and(userWrapper -> userWrapper.like(SysUser::getUsername, sysUserQueryVo.getKeyword())
                            .or()
                            .like(SysUser::getName, sysUserQueryVo.getKeyword())
                            .or()
                            .like(SysUser::getPhone, sysUserQueryVo.getKeyword())
                    );
        }
        if (StringUtils.isNotBlank(sysUserQueryVo.getCreateTimeBegin()) && StringUtils.isNotBlank(sysUserQueryVo.getCreateTimeEnd())) {
            queryWrapper.and(userWrapper -> userWrapper
                    .ge(SysUser::getCreateTime, sysUserQueryVo.getCreateTimeBegin())
                    .le(SysUser::getCreateTime, sysUserQueryVo.getCreateTimeEnd()));
        }
        queryWrapper.eq(SysUser::getIsDeleted, 0);
        queryWrapper.orderByDesc(SysUser::getId);
        IPage<SysUser> page = baseMapper.selectPage(iPage, queryWrapper);
        return Result.ok(page);
    }

    /**
     * 根据用户ID获取信息
     *
     * @param id 用户ID
     * @return Result
     */
    @Override
    public Result getUserByUserId(String id) {
        LambdaQueryWrapper<SysUser> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SysUser::getId, id);
        SysUser sysUser = baseMapper.selectOne(queryWrapper);
        if (sysUser == null) {
            Result.fail();
        }
        return Result.ok(sysUser);
    }

    /**
     * 用户保存业务
     *
     * @param sysUser 用户参数实体类
     * @return Result
     */
    @Override
    public Result saveSysUser(SysUser sysUser) {
//        MD加盐加密
        String password = MD5.encrypt(sysUser.getPassword() + UserConstants.USER_SLAT);
        sysUser.setPassword(password);
        int row = baseMapper.insert(sysUser);
        if (row == 0) {
            return Result.fail();
        }
        return Result.ok();
    }

    /**
     * 更新用户业务
     *
     * @param sysUser 更新用户参数实体类
     * @return Result
     */
    @Override
    public Result updateSysUSer(SysUser sysUser) {
//        先校验密码是否相等
        SysUser one = baseMapper.selectOne(new LambdaQueryWrapper<SysUser>()
                .eq(SysUser::getId, sysUser.getId()));
        if(!one.getPassword().equals(sysUser.getPassword())){
//            加密
            String password = MD5.encrypt(sysUser.getPassword() + UserConstants.USER_SLAT);
            sysUser.setPassword(password);
        }
        int row = baseMapper.updateById(sysUser);
        if (row == 0) {
            return Result.fail();
        }
        return Result.ok();
    }

    /**
     * 根据用户ID删除用户
     *
     * @param id 用户ID
     * @return Result
     */
    @Override
    public Result removeSysUserById(String id) {
        int row = baseMapper.deleteById(id);
        if (row == 0) {
            return Result.fail();
        }
        return Result.ok();
    }

    /**
     * 用户批量删除业务
     *
     * @param ids 用户id集合
     * @return Result
     */
    @Override
    public Result batchRemove(List<String> ids) {
        ids.stream().forEach(id -> {
            baseMapper.deleteById(id);
        });
        return Result.ok();
    }

    /**
     * 根据用户ID更新用户状态业务
     *
     * @param id     用户ID
     * @param status 用户状态
     * @return Result
     */
    @Override
    public Result updateUserStatus(String id, Integer status) {
        LambdaQueryWrapper<SysUser> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SysUser::getId, id);
        SysUser sysUser = baseMapper.selectOne(queryWrapper);
        sysUser.setStatus(status);
        int row = baseMapper.updateById(sysUser);
        if (row == 0) {
            return Result.fail();
        }
        if (status == 0) {
            return Result.ok().message("禁用成功");
        }
        return Result.ok().message("激活成功");
    }

    /**
     * 根据用户ID获取用户角色数据业务
     * 1. 获取全部的角色数据
     * 2. 获取当前用户分配角色数据
     * 3. 封装返回对象<Map>返回
     *
     * @param userId 用户ID
     * @return Result
     */
    //TODO:  没做分布式事务处理
    @Override
    public Result toAssign(String userId) {
        Result<List<SysRole>> clientAll = systemFeignClient.findAll();
        List<SysRole> roleList = clientAll.getData();
        LambdaQueryWrapper<SysUserRole> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SysUserRole::getUserId, userId);
        List<SysUserRole> sysUserRoleList = sysUserRoleMapper.selectList(queryWrapper);
        List<String> sysUserRoleIds = sysUserRoleList.stream().map(sysUserRole -> {
            return sysUserRole.getRoleId();
        }).collect(Collectors.toList());
        Map<String, Object> resMap = new HashMap<>();
        resMap.put("allRoles", roleList);
        resMap.put("userRoleIds", sysUserRoleIds);
        return Result.ok(resMap);
    }

    /**
     * 根据用户ID分配角色业务
     *
     * @param assginRoleVo 参数实体类对象
     * @return Result
     */
    @Override
    public Result saveUserRole(AssginRoleVo assginRoleVo) {
        LambdaQueryWrapper<SysUserRole> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SysUserRole::getUserId, assginRoleVo.getUserId());
        sysUserRoleMapper.delete(queryWrapper);
        List<String> ids = assginRoleVo.getRoleIdList();
        if (assginRoleVo.getRoleIdList() != null) {
            ids.forEach(id -> {
                SysUserRole userRole = new SysUserRole();
                userRole.setUserId(assginRoleVo.getUserId());
                userRole.setRoleId(id);
                sysUserRoleMapper.insert(userRole);
            });
        }
        return Result.ok();
    }

    /**
     * 用户登录业务
     *
     * @param loginVo 用户登录参数实体类
     * @return Result
     */
    @Override
    public Result Login(LoginVo loginVo) {
        SysUser user = baseMapper.selectOne(new LambdaQueryWrapper<SysUser>()
                .eq(SysUser::getUsername, loginVo.getUsername()));
        if(user == null){
            throw new CustomizeException(ResultCodeEnum.ACCOUNT_ERROR);
        }
        if(!MD5.encrypt(loginVo.getPassword()+UserConstants.USER_SLAT).equals(user.getPassword())) {
            throw new CustomizeException(ResultCodeEnum.PASSWORD_ERROR);
        }
        if(user.getStatus().intValue() == 0) {
            throw new CustomizeException(ResultCodeEnum.ACCOUNT_STOP);
        }
        Map<String, Object> map = new HashMap<>();
        map.put("token", JwtHelper.createToken(user.getId(),user.getUsername(),user.getDescription()));
        return Result.ok(map);
    }

    /**
     * 获取用户信息业务
     *
     * @param token Token
     * @return Result
     */
    @Override
    public Result info(String token) {
//        从token取用户姓名
        String username = JwtHelper.getUsername(token);
        SysUser user = this.getUserByUsername(username);
        String userId = user.getId();
        //根据用户id获取菜单权限值
        //TODO ： 远程调用system-service
        List<RouterVo> routerVoList = systemFeignClient.findUserMenuList(userId);
        System.out.println(routerVoList);
        //根据用户id获取用户按钮权限
        List<String> permsList = systemFeignClient.findUserPermsList(user.getId());
        //TODO END
        Map<String, Object> map = new HashMap<>();
        map.put("name", username);
        map.put("avatar", user.getHeadUrl());
        //当前权限控制使用不到，我们暂时忽略
        map.put("roles",  new HashSet<>());
        log.info("SysUserServiceImpl.info业务结束,结果:{}",permsList);
        map.put("buttons", permsList);
        map.put("routers", routerVoList);
        log.info("SysUserServiceImpl.info业务结束,结果:{}",routerVoList);
        return Result.ok(map);
    }

    /**
     *                      根据用户名获取对象业务
     * @param userName      用户姓名
     * @return
     */
    @Override
    public SysUser getUserByUsername(String userName){
        return baseMapper.selectOne(new LambdaQueryWrapper<SysUser>()
                .eq(SysUser::getUsername,userName));
    }
}
